package g

import (
	"fmt"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"sync"
)

var (
	once sync.Once
	db   *gorm.DB
)

func DB() *gorm.DB {
	once.Do(func() {
		db = InitDatabase()
	})

	return db
}

func InitDatabase() *gorm.DB {
	config := viper.GetStringMapString("database")
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", config["user"], config["pass"], config["host"], config["port"], config["name"])
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix: "beesoft_",
		},
	})

	//sqlDB, err := sql.Open("mysql", "mydb_dsn")
	//db, err := gorm.Open(mysql.New(mysql.Config{
	//DriverName: "my_mysql_driver",
	//Conn: sqlDB,
	//	DSN:                       "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
	//	DefaultStringSize:         256,
	//	DisableDatetimePrecision:  true,
	//	DontSupportRenameIndex:    true,
	//	DontSupportRenameColumn:   true,
	//	SkipInitializeWithVersion: false,
	//}), &gorm.Config{})

	//dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
	//db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

	//sqlDB, err := sql.Open("pgx", "mydb_dsn")
	//db, err := gorm.Open(postgres.New(postgres.Config{
	//DriverName: "cloudsqlpostgres",
	//	Conn: sqlDB,
	//	DSN: "user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai",
	//	PreferSimpleProtocol: true, // disables implicit prepared statement usage
	//}), &gorm.Config{})

	//db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{}) // github.com/glebarez/sqlite // file::memory:?cache=shared
	//dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
	//db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})
	//dsn := "clickhouse://gorm:gorm@localhost:9942/gorm?dial_timeout=10s&read_timeout=20s"
	//db, err := gorm.Open(clickhouse.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect to database")
	}

	//sqlDB, err := db.DB()
	//sqlDB.SetMaxIdleConns(10)
	//sqlDB.SetMaxOpenConns(100)
	//sqlDB.SetConnMaxLifetime(time.Hour)

	//db.Use(dbresolver.Register(dbresolver.Config{
	//	Sources:           []gorm.Dialector{mysql.Open("dsn1")},
	//	Replicas:          []gorm.Dialector{mysql.Open("dsn2"), mysql.Open("dsn3")},
	//	Policy:            dbresolver.RandomPolicy{},
	//	TraceResolverMode: true,
	//}).Register(dbresolver.Config{
	//	Replicas: []gorm.Dialector{mysql.Open("dsn5")},
	//}, &User{}).
	//	SetConnMaxIdleTime(time.Hour).
	//	SetConnMaxLifetime(24 * time.Hour).
	//	SetMaxIdleConns(100).
	//	SetMaxOpenConns(200))
	//db.Use(sharding.Register(sharding.Config{
	//	ShardingKey:         "user_id",
	//	NumberOfShards:      64,
	//	PrimaryKeyGenerator: sharding.PKSnowflake,
	//}, "orders"))
	//db.Use(prometheus.New(prometheus.Config{
	//	DBName:          "db1", // 使用 `DBName` 作为指标 label
	//	RefreshInterval: 15,    // 指标刷新频率（默认为 15 秒）
	//	PushAddr:        "prometheus pusher address", // 如果配置了 `PushAddr`，则推送指标
	//	StartServer:     true,  // 启用一个 http 服务来暴露指标
	//	HTTPServerPort:  8080,  // 配置 http 服务监听端口，默认端口为 8080 （如果您配置了多个，只有第一个 `HTTPServerPort` 会被使用）
	//	MetricsCollector: []prometheus.MetricsCollector {
	//		&prometheus.MySQL{
	//			VariableNames: []string{"Threads_running"},
	//		},
	//	},  // 用户自定义指标
	//}))
	//&prometheus.MySQL{
	//	// 指标名前缀，默认为 `gorm_status_`
	//	// 例如： Threads_running 的指标名就是 `gorm_status_Threads_running`
	//	Prefix: "gorm_status_",
	//	// 拉取频率，默认使用 Prometheus 的 RefreshInterval
	//	Interval: 100,
	//	// 从 SHOW STATUS 选择变量变量，如果不设置，则使用全部的状态变量
	//	VariableNames: []string{"Threads_running"},
	//}

	//db.Set("gorm:table_options", "ENGINE=Distributed(cluster, default, hits)").AutoMigrate(&model.Area{})

	return db
}
